/********************************************
功能:DHT11 在raspberry pi3上驱动程序
日期:2017.6.10
GPIO=
vopo123@126.com
********************************************/

#include <wiringPi.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

//raspi3B+
unsigned int GPIO = 4;//模块GPIO脚
//#define DPRINTK(x...) printf(x);
#define DPRINTK(x...) 
unsigned char U8_data[5];
int get_dht_data(float* temp,float* humi);
int init_dht(void);

int main()
{
	float ftemp=0.0,fhumi=0.0;
	if(wiringPiSetup()==-1){
		printf("pi setup err...\n");
		return 1;
	}
	while(1)
	{
	   	if(get_dht_data(&ftemp,&fhumi)==0)
			printf("RH=%2f %%,T=%2f oC.\n",fhumi,ftemp);
		sleep(3);
	}
	return 0;
}


int init_dht(void)
{	
	int l_flag=0,h_flag=0,flag=0;
	int i=0,j=0;
	int bit_flag[40];
	unsigned tmp;
	unsigned char  U8comdata,U8temp[40];

	DPRINTK("DHT11 init...");
	//GPIO设置为输出
      	pinMode(GPIO, OUTPUT);//设置输出	
	//输出0
	digitalWrite(GPIO, LOW);  //输出低电平	
	//延时19ms
	//usleep(18*1000);
	delay(18);
	//输出1	
        digitalWrite(GPIO, HIGH);  //输出高电平				
	//延时30us
	//usleep(20);
	delayMicroseconds(35);	
	//设置为输入
      	pinMode(GPIO,INPUT);//设置输入
	//读GPIO	
	tmp = digitalRead(GPIO) ;	
//	DPRINTK("gpio=%d\n",tmp);

	if(!tmp)
	{	
		while(!(digitalRead(GPIO)) ){
			if((l_flag++)>85) break;
			delayMicroseconds(1);
		}//从机80us低电平

		while(digitalRead(GPIO)){
			if((h_flag++)>85) break;
			delayMicroseconds(1);
		}//从机80us高电平
		//read 40bit data
		for(i=0;i<40;i++){
			flag = 0;
			while(!(digitalRead(GPIO)) ){
				if((flag++)>70) break;
				delayMicroseconds(1);
			}//从机50us低电平
			flag =0;
			while(digitalRead(GPIO) ){
				if((flag++)>90) break;
				delayMicroseconds(1);
			}//从机高电平//高电平大于70us为"1",否则26-28us为"0"		

			if(flag>30){
				U8temp[i]=1;
			}else{
				U8temp[i]=0;
			}
			bit_flag[i]=flag;		   	 
		}
		for(i=0;i<40;i++){
			U8comdata<<=1;
			U8comdata|=U8temp[i];
			if((i+1)%8 == 0){
				U8_data[j]=U8comdata;
				j++;
			}		
//			DPRINTK("[%d]flag=%d,val=%d--",i,bit_flag[i],U8temp[i]);
		}
		DPRINTK("L 80us flag=%d\n",l_flag);
		DPRINTK("H 80us flag=%d \n",h_flag);			
	}else{DPRINTK("L err..\n");}	
	return 0;				
}


int get_dht_data(float* temp,float* humi)
{
	char crr=0;
	int s=0;	
	int temp_d=0,humi_d=0;
					
	init_dht();
	for(s;s<4;s++){
//		printf("data[%d]=%x\n",s,U8_data[s]);
		crr+=U8_data[s];
	}	
//	printf("data[4]=%x,crr=%x\n",U8_data[4],crr);
		
	if(crr==U8_data[4]){
		humi_d = U8_data[0];
		temp_d = U8_data[2];
		*humi = humi_d;
		*temp = temp_d;
		printf("\n+---RH=%d %%,T=%d oC.\n",humi_d,temp_d);
	}else{
		printf("crr err %X\n",crr);
		return -1;
	}		
	return 0;
}



